home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 30
/
Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso
/
Aminet
/
util
/
boot
/
FixGetMsg.lha
/
FixGetMsg.doc
< prev
next >
Wrap
Text File
|
1999-01-13
|
3KB
|
52 lines
Description:
FixGetMsg is a patch to get around a problem that occurs when the Exec
GetMsg() is called in a tight loop on a fast CPU such as the 68060. This
shouldn't happen in well-written code, but dumb code that uses polling of
GetMsg() rather than waiting for a signal may do this. The result can be a
complete lockup of the system due to interrupt exclusion.
Usage:
Running FixGetMsg installs the patch and exits, provided that GetMsg() is
not already patched and has the expected first instruction. The patch
requires 32 bytes of RAM. FixGetMsg can be installed in User-Startup.
Details of the Problem and the Fix:
The problem is that GetMsg() disables interrupts in order to stabilize the
port queue, which is ordinarily reasonable, but when it is called in a
tight loop the duration of the time that interrupts are enabled is rather
short. Due to pipelining, by the time the enable actually gets turned on
in the hardware, the code may already be executing in the disabled section.
This is a possible race on any processor (even a 7MHz 68000), but is
avoided by having the interrupt stubs check the enable before dispatching
to the handler. In this tight looping case however, the interrupt routines
may find the interrupts disabled at the time of the interrupt *every time
around the loop*, thus locking up the system.
FixGetMsg patches GetMsg() to avoid this problem by checking the emptiness
of the queue before disabling interrupts, which can be done safely. This
slightly increases the overhead in the normal (nonempty) case, but avoids
the disabling altogether when the queue is empty. The patch includes a
counter for the cases where the queue was empty, to get an idea of how
often this happens. The counter is the longword immediately preceding the
patched version of GetMsg(), and can be inspected with a debugger. The
count should be very large after running LoopGetMsg.
The program LoopGetMSg is used to test this. It calls GetMsg() on an empty
dummy MsgPort 10 million times and exits. On my 060/50 system without the
patch, this locks the system for ~50 seconds. With the patch, the system
continues normally and the program exits in about 4 seconds.
For some reason that I don't really understand, disabling the write buffer
with cpu060 doesn't avoid the problem in the unpatched system, but
disabling Superscalar mode does. Perhaps the latter only helps by slowing
down the CPU, rather than by its logical effect.
Frederick H. G. Wright II
fw@well.com
13-Jan-1999